#pragma once
#include "LinkedQueue.h"

template <typename T>
class ConcurrentLinkedQueue : public LinkedQueue<T>
{
private :
	LockHelper m_oLockHelper;
public :
	ConcurrentLinkedQueue(int a_nMaxSize);
	~ConcurrentLinkedQueue();

	virtual void offer(T a_oData);
	virtual T poll();
	virtual T peek();
	virtual bool canOffer();
	virtual bool canPoll();
	virtual int getDataCount();

};

template <typename T>
ConcurrentLinkedQueue<T>::ConcurrentLinkedQueue(int a_nMaxSize) : LinkedQueue<T>(a_nMaxSize)
{
}

template <typename T>
ConcurrentLinkedQueue<T>::~ConcurrentLinkedQueue()
{
}

template <typename T>
void ConcurrentLinkedQueue<T>::offer(T a_oData) {

	m_oLockHelper.lock();
	LinkedQueue<T>::offer(a_oData);
	m_oLockHelper.unlock();
}

template <typename T>
T ConcurrentLinkedQueue<T>::poll() {

	m_oLockHelper.lock();
	T polledData = LinkedQueue<T>::poll();
	m_oLockHelper.unlock();

	return polledData;
}

template <typename T>
T ConcurrentLinkedQueue<T>::peek() {

	m_oLockHelper.lock();
	T peekedData = LinkedQueue<T>::peek();
	m_oLockHelper.unlock();

	return peekedData;
}

template <typename T>
bool ConcurrentLinkedQueue<T>::canOffer() {

	m_oLockHelper.lock();
	bool offerable = LinkedQueue<T>::canOffer();
	m_oLockHelper.unlock();

	return offerable;
}

template <typename T>
bool ConcurrentLinkedQueue<T>::canPoll() {

	m_oLockHelper.lock();
	bool pollable = LinkedQueue<T>::canPoll();
	m_oLockHelper.unlock();

	return pollable;
}

template <typename T>
int ConcurrentLinkedQueue<T>::getDataCount() {

	m_oLockHelper.lock();
	int dataCount = LinkedQueue<T>::getDataCount();
	m_oLockHelper.unlock();

	return dataCount;
}